namespace Spotted.Storage.Queues.ViewModels
{
    using System;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Text;
    using Microsoft.WindowsAzure.Samples.Phone.Storage;

    public class QueueDetailsPageViewModel : INotifyPropertyChanged
    {
        private readonly ICloudQueueClient client;

        private ICloudQueue queue;
        private string queueName;
        private bool isBusy;
        private string queueMessageContent;
        private string message;

        public QueueDetailsPageViewModel()
            : this(CloudStorageContext.Current.Resolver.CreateCloudQueueClient())
        {
        }

        public QueueDetailsPageViewModel(ICloudQueueClient client)
        {
            this.client = client;
            this.CloudQueueMessages = new ObservableCollection<CloudQueueMessage>();
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public string QueueName
        {
            get
            {
                return this.queueName;
            }

            set
            {
                this.queueName = value;
                this.NotifyPropertyChanged("QueueName");
            }
        }

        public ICloudQueue Queue
        {
            get
            {
                return this.queue;
            }

            set
            {
                this.queue = value;
                this.NotifyPropertyChanged("Queue");
            }
        }

        public bool IsBusy
        {
            get
            {
                return this.isBusy;
            }

            set
            {
                if (this.isBusy != value)
                {
                    this.isBusy = value;
                    this.NotifyPropertyChanged("IsBusy");
                }
            }
        }

        public string QueueMessageContent
        {
            get
            {
                return this.queueMessageContent;
            }

            set
            {
                if (this.queueMessageContent != value)
                {
                    this.queueMessageContent = value;
                    this.NotifyPropertyChanged("QueueMessageContent");
                }
            }
        }

        public string Message
        {
            get
            {
                return this.message;
            }

            set
            {
                if (this.message != value)
                {
                    this.message = value;
                    this.NotifyPropertyChanged("Message");
                }
            }
        }

        public ObservableCollection<CloudQueueMessage> CloudQueueMessages { get; set; }

        public void QueueMessage()
        {
            this.Message = "Queing message...";
            this.IsBusy = true;

            try
            {
                this.Queue = this.client.GetQueueReference(this.QueueName);
                this.Queue.AddMessage(
                    new CloudQueueMessage { AsBytes = Encoding.UTF8.GetBytes(this.QueueMessageContent) },
                    r =>
                    {
                        this.Message = r.Success
                            ? "Message successfully queued!"
                            : string.Concat("Error: ", r.ErrorMessage);

                        this.IsBusy = false;
                    });
            }
            catch (Exception exception)
            {
                this.IsBusy = false;
                this.Message = string.Concat("Error: ", exception.Message);
            }
        }

        public void DequeueMessage()
        {
            this.Message = "Dequeing message...";
            this.IsBusy = true;
            try
            {
		        this.Queue = this.client.GetQueueReference(this.QueueName);
                this.Queue.GetMessage(
                    s =>
                    {
                        if (s.Success)
                        {
                            if (s.Response == null)
                            {
                                this.Message = "Queue is empty";
                                this.IsBusy = false;
                            }
                            else
                            {
                                this.Queue.DeleteMessage(
                                    s.Response,
                                    r =>
                                    {
                                        if (r.Success)
                                        {
                                            this.CloudQueueMessages.Add(s.Response);
                                            this.Message = "Message successfully dequeued!";
                                        }
                                        else
                                        {
                                            this.Message = string.Concat("Error: ", r.ErrorMessage);
                                        }

                                        this.IsBusy = false;
                                    });
                            }
                        }
                        else
                        {
                            this.Message = string.Concat("Error: ", s.ErrorMessage);
                            this.IsBusy = false;
                        }
                    });
            }
            catch (Exception exception)
            {
                this.IsBusy = false;
                this.Message = string.Concat("Error: ", exception.Message);
            }
        }

        protected virtual void NotifyPropertyChanged(string propertyName)
        {
            var propertyChanged = this.PropertyChanged;
            if (propertyChanged != null)
                propertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
